{-# OPTIONS -XExistentialQuantification  #-}

module Sim.PixObject (
   PixObject(..),

   PixObsObject(..),

   PointSource(..),
   EllipseSource(..)
 ) where

import Sim.PSF       ( PSF, Pixel )
import Sim.CRayTrace ( Trace(..) )
import Sim.Helper    ( floor' )
import Sim.PhysTypes

type SemiX = Double
type SemiY = Double

--data PointSource   = PointSource PhotonFlux Coord
data PointSource   = PointSource EnergyDist PhotonFlux Coord
data EllipseSource = EllipseSource (Angle, SemiX, SemiY) PhotonFlux Coord

-- Тип-контейнер для наблюдаемых объектов, для которых возможна пиксилизация.

data PixObsObject = forall a . PixObject a => PixObsObject a

-- Определение класса объектов, которые могут быть представлены в пиксельном виде.

class PixObject obj where
   pixelization :: PSF -> ADF -> obj -> [Pixel]

--------------------------------------------------------------------------------------------------

instance PixObject PixObsObject where
   pixelization psf adf (PixObsObject o) = pixelization psf adf o

--------------------------------------------------------------------------------------------------

instance PixObject Trace where
   pixelization _ _ (Trace (x,y) (x',y') fi) =  [( (floor' $ x+i*dx, floor' $ y+i*dy), k ) | i<-[0..n]]
      where
        k  = 20 / sin fi
        dx = (x'-x)/n
        dy = (y'-y)/n
        n  = 50 * sqrt ( (x-x')^2 + (y-y')^2 )

--------------------------------------------------------------------------------------------------

instance PixObject PointSource where
--   pixelization psf (PointSource i (u,v)) = [ (p, i*v) | (p,v) <- psf (u,v) ]
--{--
   pixelization psf adf (PointSource s i uv) = [ (p, i*v) | (p,v) <- pixels s uv psf adf ]
{--
     where
       lb = 1150
       rb = 5000
 
       adf' = None

       adf :: ADF
       adf  = Grism [so',to'] fo [so,to]
          where
             fo  = (0.1, 0)

             so  = [ (0.5, ( (duv_s wl)), wl) | wl <- [lb, lb+5 .. rb]]
             so' = [ (0.5, (-(duv_s wl)), wl) | wl <- [lb, lb+5 .. rb]]

             to  = [ (0.4, ( duv_s rb + (duv_t wl)), wl) | wl <- [lb, lb+5 .. rb]]
             to' = [ (0.4, (-duv_s rb - (duv_t wl)), wl) | wl <- [lb, lb+5 .. rb]]

             duv_s wl = (du,dv)
               where
                 du = 0.1 * (wl - lb)/(rb-lb) / 60
                 dv = 0.0 * (wl - lb)/(rb-lb) / 60

             duv_t wl = (du,dv)
               where
                 du = 0.2 * (wl - lb)/(rb-lb) / 60
                 dv = 0.0 * (wl - lb)/(rb-lb) / 60
--       pixels =  psf uv

--}

--------------------------------------------------------------------------------------------------

instance PixObject EllipseSource where
   pixelization psf adf (EllipseSource (a,x,y) i (u,v)) = undefined


pixels s uv psf (Grism lorders zorder rorders) = lo ++ fo ++ ro
  where
    fo = [(p, i*v) | (p,v) <- psf (uv+xy)]
       where
         (i,xy) = zorder
         
    ro = concatMap pixOrder rorders
    lo = concatMap pixOrder lorders
    
    pixOrder order = concat [ [(p, i * v * s wl) | (p,v) <- psf (uv+xy)] | (i,xy,wl) <- order ]

pixels _ uv psf None = psf uv